<script setup lang="ts">
import { ChevronDoubleLeftIcon, ChevronDoubleRightIcon } from '@heroicons/vue/24/outline'
import { breakpointsTailwind, useBreakpoints, useOffsetPagination } from '@vueuse/core'
import { computed } from 'vue'

interface Props {
  total: number
  pageSizes?: number[]
}

const { total, pageSizes = [10, 20, 50, 100] } = defineProps<Props>()

const page = defineModel<number>('page', { default: 1 })
const pageSize = defineModel<number>('pageSize', { default: 10 })

const breakpoints = useBreakpoints(breakpointsTailwind)
const isMobile = breakpoints.smaller('md')

const { pageCount, isFirstPage, isLastPage, prev, next } = useOffsetPagination({
  total: () => total,
  page,
  pageSize,
  onPageChange: ({ currentPage }) => (page.value = currentPage),
  onPageSizeChange: ({ currentPageSize }) => (pageSize.value = currentPageSize)
})

const visiblePages = computed(() => {
  const maxVisible = isMobile.value ? 3 : 7

  if (pageCount.value <= maxVisible) return Array.from({ length: pageCount.value }, (_, i) => i + 1)

  if (isMobile.value) {
    if (isFirstPage.value) return [1, 2, '...', pageCount.value]
    if (isLastPage.value) return [1, '...', pageCount.value - 1, pageCount.value]
    return [1, '...', page.value, '...', pageCount.value]
  }

  // Desktop
  if (page.value < 5) return [1, 2, 3, 4, 5, '...', pageCount.value]
  if (page.value > pageCount.value - 4) return [1, '...', pageCount.value - 4, pageCount.value - 3, pageCount.value - 2, pageCount.value - 1, pageCount.value]
  return [1, '...', page.value - 1, page.value, page.value + 1, '...', pageCount.value]
})
</script>

<template>
  <div class="flex-between gap-4">
    <select class="select select-sm hidden w-30 md:block" id="page-size" name="page-size" v-model="pageSize">
      <option v-for="size in pageSizes" :key="size" :value="size">{{ size }}/{{ 'page' }}</option>
    </select>

    <div class="text-base-content/70 space-x-1 font-medium">
      <span class="text-primary hidden font-bold md:inline">{{ Math.min((page - 1) * pageSize + 1, total) }}-{{ Math.min(page * pageSize, total) }}</span>
      <span class="hidden md:inline">{{ 'of' }}</span>
      <span class="text-primary font-bold">{{ total }}</span>
      <span>{{ 'results' }}</span>
    </div>

    <!-- 分页按钮 -->
    <div class="join justify-center md:ml-auto">
      <button class="join-item btn btn-sm" :disabled="isFirstPage" @click="prev">
        <ChevronDoubleLeftIcon class="size-4" />
        <span class="hidden md:inline">{{ 'Prev' }}</span>
      </button>

      <template v-if="visiblePages.length > 0" v-for="pageNumber in visiblePages" :key="pageNumber">
        <button v-if="pageNumber === '...'" class="join-item btn btn-sm pointer-events-none">...</button>
        <button v-else class="join-item btn btn-sm" :class="{ 'btn-primary': pageNumber === page }" @click="page = Number(pageNumber)">
          {{ pageNumber }}
        </button>
      </template>

      <button class="join-item btn btn-sm" :disabled="isLastPage" @click="next">
        <span class="hidden md:inline">{{ 'Next Page' }}</span>
        <ChevronDoubleRightIcon class="size-4" />
      </button>
    </div>
  </div>
</template>
